home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / caplog.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-20  |  7.2 KB  |  294 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2001 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include <stdio.h>
  19.  
  20. #include <windows.h>
  21. #include <commctrl.h>
  22. #include <commdlg.h>
  23.  
  24. #include "resource.h"
  25. #include "Error.h"
  26.  
  27. #include "caplog.h"
  28.  
  29. extern HINSTANCE g_hInst;
  30.  
  31. CaptureLog::CaptureLog() {
  32.     nEvents = nEventsBlock = 0;
  33.     pceb = NULL;
  34. }
  35.  
  36. CaptureLog::~CaptureLog() {
  37.     Dispose();
  38. }
  39.  
  40. void CaptureLog::Dispose() {
  41.     CapEventBlock *pceb2;
  42.  
  43.     while(pceb2 = listBlocks.RemoveHead())
  44.         delete pceb2;
  45.  
  46.     nEvents = nEventsBlock = 0;
  47.     pceb = NULL;
  48. }
  49.  
  50. CapEvent *CaptureLog::GetNewRequest() {
  51.     if (!pceb || nEventsBlock >= 256) {
  52.         pceb = new CapEventBlock();
  53.  
  54.         if (!pceb)
  55.             return NULL;
  56.  
  57.         listBlocks.AddTail(pceb);
  58.  
  59.         nEventsBlock = 0;
  60.     }
  61.  
  62.     ++nEvents;
  63.  
  64.     return &pceb->ev[nEventsBlock++];
  65. }
  66.  
  67. bool CaptureLog::LogVideo(DWORD dwTimeStampReceived, DWORD dwBytes, DWORD dwTimeStampRecorded) {
  68.     CapEvent *pce = GetNewRequest();
  69.  
  70.     if (!pce)
  71.         return false;
  72.  
  73.     pce->type = CapEvent::VIDEO;
  74.     pce->dwTimeStampReceived = dwTimeStampReceived;
  75.     pce->dwBytes = dwBytes;
  76.     pce->video.dwTimeStampRecorded = dwTimeStampRecorded;
  77.  
  78.     return true;
  79. }
  80.  
  81. bool CaptureLog::LogAudio(DWORD dwTimeStampReceived, DWORD dwBytes, LONG lVideoDelta) {
  82.     CapEvent *pce = GetNewRequest();
  83.  
  84.     if (!pce)
  85.         return false;
  86.  
  87.     pce->type = CapEvent::AUDIO;
  88.     pce->dwTimeStampReceived = dwTimeStampReceived;
  89.     pce->dwBytes = dwBytes;
  90.     pce->audio.lVideoDelta = lVideoDelta;
  91.  
  92.     return true;
  93. }
  94.  
  95. ///////////////////////////////////////////////////////////////////////////
  96.  
  97. void CaptureLog::GetDispInfo(NMLVDISPINFO *nldi) {
  98.     static const char *szTypes[]={ "Video", "Audio" };
  99.     CapEvent *pev = (CapEvent *)nldi->item.lParam;
  100.  
  101.     nldi->item.mask            = LVIF_TEXT;
  102.     nldi->item.pszText[0]    = 0;
  103.  
  104.     switch(nldi->item.iSubItem) {
  105.     case 0:
  106.         nldi->item.pszText = (char *)szTypes[pev->type];
  107.         break;
  108.     case 1:
  109.         _snprintf(nldi->item.pszText, nldi->item.cchTextMax, "%d.%03d", pev->dwTimeStampReceived/1000, pev->dwTimeStampReceived%1000);
  110.         break;
  111.     case 2:
  112.         if (pev->type == CapEvent::AUDIO)
  113.             nldi->item.pszText[0] = 0;
  114.         else
  115.             _snprintf(nldi->item.pszText, nldi->item.cchTextMax, "%d.%03d", pev->video.dwTimeStampRecorded/1000, pev->video.dwTimeStampRecorded%1000);
  116.         break;
  117.     case 3:
  118.         _snprintf(nldi->item.pszText, nldi->item.cchTextMax, "%d", pev->dwBytes);
  119.         break;
  120.     }
  121. }
  122.  
  123. BOOL CaptureLog::DlgProc2(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  124.     static char *szColumnNames[]={ "Type","Received","Recorded","Bytes" };
  125.     static int iColumnWidths[]={ 100,75,75,75 };
  126.  
  127.     int index;
  128.     HWND hwndItem;
  129.  
  130.     switch(msg) {
  131.     case WM_INITDIALOG:
  132.         {
  133.             LV_COLUMN lvc;
  134.             CapEventBlock *pceb = listBlocks.AtHead(), *pceb_next;
  135.             int i, cnt;
  136.  
  137.             hwndItem = GetDlgItem(hdlg, IDC_EVENTS);
  138.  
  139.             ListView_SetExtendedListViewStyleEx(hwndItem, LVS_EX_FULLROWSELECT , LVS_EX_FULLROWSELECT);
  140.  
  141.             for (i=0; i<4; i++) {
  142.                 lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  143.                 lvc.fmt = LVCFMT_LEFT;
  144.                 lvc.cx = iColumnWidths[i];
  145.                 lvc.pszText = szColumnNames[i];
  146.  
  147.                 ListView_InsertColumn(hwndItem, i, &lvc);
  148.             }
  149.  
  150.             index = 0;
  151.             cnt = nEvents;
  152.  
  153. //            FILE *f = fopen("f:\\caplog.txt", "w");
  154.  
  155.             while(pceb_next = pceb->NextFromHead()) {
  156.                 CapEvent *evptr = pceb->ev;
  157.                 int mx = cnt>256 ? 256 : cnt;
  158.  
  159.  
  160.                 cnt -= mx;
  161.  
  162.                 for(i=mx; i; i--) {
  163.                     LVITEM li;
  164.  
  165.                     li.mask        = LVIF_TEXT|LVIF_PARAM;
  166.                     li.iSubItem    = 0;
  167.                     li.iItem    = index++;
  168.                     li.pszText    = LPSTR_TEXTCALLBACK;
  169.                     li.lParam    = (LPARAM)evptr++;
  170.  
  171.                     ListView_InsertItem(hwndItem, &li);
  172.  
  173. //                    if (evptr->type == CapEvent::VIDEO) {
  174. //                        fprintf(f, "%-10d %-10d %-10d\n", evptr->dwTimeStampReceived, evptr->video.dwTimeStampRecorded, evptr->dwBytes);
  175. //                    }
  176.                 }
  177.  
  178.                 pceb = pceb_next;
  179.             }
  180.  
  181. //            fclose(f);
  182.         }
  183.         return FALSE;
  184.  
  185.     case WM_NOTIFY:
  186.         {
  187.             NMHDR *nm = (NMHDR *)lParam;
  188.  
  189.             if (nm->idFrom == IDC_EVENTS) {
  190.                 NMLVDISPINFO *nldi = (NMLVDISPINFO *)nm;
  191.  
  192.                 switch(nm->code) {
  193.                 case LVN_GETDISPINFO:
  194.                     GetDispInfo(nldi);
  195.                     return TRUE;
  196.                 }
  197.             }
  198.         }
  199.         break;
  200.  
  201.     case WM_COMMAND:
  202.         if (LOWORD(wParam) == IDC_SAVE) {
  203.             OPENFILENAME ofn;
  204.             char szFile[MAX_PATH];
  205.  
  206.             szFile[0] = 0;
  207.  
  208.             ofn.lStructSize            = sizeof(OPENFILENAME);
  209.             ofn.hwndOwner            = hdlg;
  210.             ofn.lpstrFilter            = "Comma separated values (*.csv)\0*.csv\0";
  211.             ofn.lpstrCustomFilter    = NULL;
  212.             ofn.nFilterIndex        = 1;
  213.             ofn.lpstrFile            = szFile;
  214.             ofn.nMaxFile            = sizeof szFile;
  215.             ofn.lpstrFileTitle        = NULL;
  216.             ofn.nMaxFileTitle        = NULL;
  217.             ofn.lpstrInitialDir        = NULL;
  218.             ofn.lpstrTitle            = "Save capture timing data";
  219.             ofn.Flags                = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_ENABLESIZING;
  220.             ofn.lpstrDefExt            = NULL;
  221.  
  222.             if (GetSaveFileName(&ofn)) {
  223.                 FILE *f = fopen(szFile, "w");
  224.  
  225.                 try {
  226.                     if (!f)
  227.                         throw MyError("Cannot save file: %s", strerror(NULL));
  228.  
  229.                     CapEventBlock *pceb = listBlocks.AtHead(), *pceb_next;
  230.                     int i, cnt;
  231.  
  232.                     cnt = nEvents;
  233.  
  234.                     while(pceb_next = pceb->NextFromHead()) {
  235.                         CapEvent *evptr = pceb->ev;
  236.                         int mx = cnt>256 ? 256 : cnt;
  237.  
  238.                         cnt -= mx;
  239.  
  240.                         for(i=mx; i; i--) {
  241.                             if (evptr->type == CapEvent::VIDEO) {
  242.                                 fprintf(f, "video,%u,%u,%u,-1\n", evptr->dwTimeStampReceived, evptr->video.dwTimeStampRecorded, evptr->dwBytes);
  243.                             } else if (evptr->type == CapEvent::AUDIO) {
  244.                                 fprintf(f, "audio,%u,%u,%u,%d\n", evptr->dwTimeStampReceived, evptr->dwTimeStampReceived, evptr->dwBytes, evptr->audio.lVideoDelta);
  245.                             }
  246.                             ++evptr;
  247.                         }
  248.  
  249.                         pceb = pceb_next;
  250.                     }
  251.  
  252.                     if (ferror(f) || fclose(f))
  253.                         throw MyError("Cannot save file: %s", strerror(NULL));
  254.  
  255.                 } catch(MyError e) {
  256.                     e.post(hdlg, "Log write error");
  257.                 }
  258.  
  259.                 if (f) fclose(f);
  260.             }
  261.  
  262.             return TRUE;
  263.         } else if (LOWORD(wParam) == IDOK) {
  264.             EndDialog(hdlg, 0);
  265.             return TRUE;
  266.         }
  267.  
  268.         break;
  269.  
  270.     case WM_CLOSE:
  271.         EndDialog(hdlg, 0);
  272.         return TRUE;
  273.     }
  274.     return FALSE;
  275. }
  276.  
  277. BOOL CALLBACK CaptureLog::DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  278.     if (msg == WM_INITDIALOG) {
  279.         SetWindowLong(hdlg, DWL_USER, lParam);
  280.         return ((CaptureLog *)lParam)->DlgProc2(hdlg, msg, wParam, lParam);
  281.     }
  282.  
  283.     CaptureLog *thisPtr = (CaptureLog *)GetWindowLong(hdlg, DWL_USER);
  284.  
  285.     if (!thisPtr)
  286.         return FALSE;
  287.  
  288.     return thisPtr->DlgProc2(hdlg, msg, wParam, lParam);
  289. }
  290.  
  291. void CaptureLog::Display(HWND hwndParent) {
  292.     DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CAPTURE_EVENTLOG), hwndParent, CaptureLog::DlgProc, (LPARAM)this);
  293. }
  294.